/**
*		@file Parent.h
*		@brief Parent class
*
*		@author Kong Ling Ming
*
*		@date 1/25/2012
*/

#ifndef PARENT_H
#define PARENT_H

#include "TNode.h"
#include "StmtTable.h"
#include <vector>
#include <sstream>
using namespace std;

/**
*		Structure to Parent relation
*/
struct ParentEntry{
	StmtNum			stmt_num_left;
	StmtNum			stmt_num_right;
};

class Parent{
public:
	/**
	*		This method will set Parent(stmt_idx_left, stmt_idx_right)
	*/
	static void		SetParent(StmtNum stmt_idx_left, StmtNum stmt_idx_right);

	/**
	*		This method will transform a vector structure to four matrix structures
	*/
	static void		RebuildParent();

	static void		CompleteParent();

	/**
	*		This method will get StmtSet of s, such that Parent(stmt_num_left, s)
	*/
	static StmtSet&	GetParentRight(StmtNum stmt_num_left);

	/**
	*		This method will get StmtSet of s, such that Parent(s, stmt_num_right)
	*/
	static StmtSet&	GetParentLeft(StmtNum stmt_num_right);

	/**
	*		This method will get StmtSet of s, such that Parent*(stmt_num_left, s)
	*/
	static StmtSet&	GetParentAdvRight(StmtNum stmt_num_left);

	/**
	*		This method will get StmtSet of s, such that Parent*(s, stmt_num_right)
	*/
	static StmtSet&	GetParentAdvLeft(StmtNum stmt_num_right);
	
	/**
	*		This method will check if Parent(stmt_num_left, stmt_num_right)
	*/
	static bool		IsParent(StmtNum stmt_num_left, StmtNum stmt_num_right);
	
	/**
	*		This method will check if Parent*(stmt_num_left, stmt_num_right)
	*/
	static bool		IsParentAdv(StmtNum stmt_num_left, StmtNum stmt_num_right);

	/**
	*		This method will return a string representation of Parent relation
	*/
	static string	ToString();

private:
	static vector<ParentEntry*>		vp_parent_entries_;
	static vector<StmtSet>			parent_table_;
	static vector<StmtSet>			parent_table_t_;
	static vector<StmtSet>			parent_adv_table_;
	static vector<StmtSet>			parent_adv_table_t_;

	static StmtSet					parent_has_s0_;	//parent(s,_),parent*(s,_)
	static StmtSet					parent_has_0s_;	//parent(_,s),parent*(_,s)
	static bool						parent_has_00_;	//parent(_,_),parent*(_,_)
};

#endif